package com.songyang.yougnsql.server.handler;

import com.songyang.yougnsql.server.Executor;
import com.songyang.yougnsql.server.YoungSqlServer;
import com.songyang.yougnsql.server.serialize.SerializeFactory;
import com.songyang.yougnsql.server.transport.YoungSQLDataPackage;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;

import java.nio.charset.StandardCharsets;

/**
 * @ClassName NettyServerHandler
 * @Description 自定义一个handler，需要继承一个netty好的适配器（有很多）
 * 这样的handler才是netty的handler
 * @date 2022/8/3 16:46
 * @Author yanceysong
 * @Version 1.0
 */
public class ServerHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        ctx.writeAndFlush(Unpooled.copiedBuffer(SerializeFactory.getEncoder().serialize(YoungSqlServer.getWelcomePackage())));
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
//        System.out.println(ctx.channel().remoteAddress()+"下线");
    }

    /**
     * 读取数据处理器方法
     *
     * @param ctx 上下文（管道pipeline，通道channel，连接的地址....）
     * @param msg 客户端发来的数据，默认是Object
     * @throws Exception 异常
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        //如果是一个耗时非常长的业务，我们需要异步执行他
        //异步执行->提交该channel对应的NIOEventLoop的taskQueue
//        ctx.channel().eventLoop().execute(()->{
//            try {
//                Thread.sleep(10000);
//            } catch (InterruptedException e) {
//                throw new RuntimeException(e);
//            }
//            System.out.println("处理接触");
//        });

//        System.out.println("server ctx=" + ctx);
        //将msg转成一个byteBuffer,这个bytebuffer是netty提供的，性能更高
        ByteBuf buf = (ByteBuf)msg;
        byte[] req = new byte[buf.readableBytes()];
        buf.readBytes(req);
        YoungSQLDataPackage pack = SerializeFactory.getEncoder().deserialize(req);
//        System.out.println("服务端收到了一条sql：" + pack.getData());
        ctx.channel().writeAndFlush(Unpooled.copiedBuffer(SerializeFactory
                .getEncoder()
                .serialize(new YoungSQLDataPackage(Executor.getExecutor().execute(pack.getData().getBytes(StandardCharsets.UTF_8)), null))));
    }

    /**
     * 读取数据读取 完毕
     *
     * @param ctx 上下文
     * @throws Exception 异常
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        //将数据写入到缓存并刷新
        //一般来讲，我们对这个发送的数据进行编码
//        ctx.writeAndFlush(Unpooled.copiedBuffer("hello",StandardCharsets.UTF_8));
//
    }


    /**
     * 发生异常地处理，关闭通道
     *
     * @param ctx   上下文
     * @param cause 异常
     * @throws Exception 异常
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.channel().close();
    }

}
